--[[------------------------------------------------------------------
--  $id$
--
--  DongleCore is the central component in the Dongle addon framework.
--  While this library doesn't provide much functionality on it's 
--  own, it provides a solid structure for the core Dongle components.
--
--  Copyright 2007 by James N. Whitehead II
------------------------------------------------------------------]]--

local major = "DongleCore-2.0"
local minor = tonumber(("$Revision: 464 $"):match("(%d+)")) or 1

assert(DongleStub, ("%s requires DongleStub."):format(major))

if DongleStub:IsNewerVersion(major, minor) then

	local lib = {
		registry = {
		},
	}

	local registry

	local L = {
		["BAD_LIBRARY_METHOD"] = "Found an invalid API entry '%s' on registration for '%s'.",
		["NO_INSTANCE_FOUND"] = "Could not find a library instance for '%s'.",
		["MISSING_EMBED_METHOD"] = "Could not find a proper 'Embed' method in core library '%s'",
		["NOT_CORE_LIBRARY"] = "'%s' is not a core library, or is not registered.",
	}

	function lib:New(name, ...)
		local obj = {}

		-- Need to build a dependency graph and ensure things are loaded
		-- in the correct order

		for i=1,select("#", ...) do
			local libname = select(i, ...)
			if not registry.corelibs[libname] then
				error(L["NOT_CORE_LIBRARY"]:format(libname), 2)
			end

			DongleStub(libname):Embed(obj)
		end

		return obj
	end

	-- RegsisterCoreAPI(version, api)
	-- This function takes in a major version name, and an external_api
	-- representing a core Dongle library.  This API is checked for 
	-- consistency, and then becomes available to any dongle addon
	-- requesting it.
	-- 
	-- Dependencies are expressed using the optional arguments to this
	-- function.  These are stored for negotation at :New() time

	function lib:RegisterCoreAPI(major, api, ...)
		if not DongleStub:HasVersion(major) then
			error(L["NO_INSTANCE_FOUND"]:format(major), 2)
		end
		
		argcheck(api, 3, "table")
		local instance = DongleStub(major)

		for idx,method in pairs(api) do
			if type(instance[method]) ~= "function" then
				error(L["BAD_LIBRARY_METHOD"]:format(method, major), 2)
			end
		end

		if type(instance.Embed) ~= "function" then
			error(L["MISSING_EMBED_METHOD"]:format(major), 2)
		end

		-- At this point, the API should be consistent, so we store
		-- the api list indexed by major version, so it can be 
		-- requested by new addons.

		registry.corelibs = registry.corelibs or {}
		registry.corelibs[major] = api

		-- Store any dependency information 
		
		registry.deps = registry.deps or {}
		registry.deps[major] = {...}
	end

	function lib:GetVersion() 
		return major,minor
	end

	local function Activate(new, old)
		if old then
			new.registry = old.registry or new.registry
		end

		registry = new.registry
	end

	local function Deactivate(old, new)
	end

	lib = DongleStub:Register(lib, Activate, Deactivate)
end
